package achievement

import (
	"encoding/json"
	table_StarMap "sanguo/node/table/excel/table/StarMap"
	table_WeaponCollection "sanguo/node/table/excel/table/WeaponCollection"
	cs_message "sanguo/protocol/cs/message"

	"github.com/golang/protobuf/proto"
)

/*
*	武器碎片的收集 Progress为当前可领取奖励的碎片数 领取时数字减
*	武器星级的收集 Progress为当前领取星级的目标值，如=3 即领取对应武器星级为3的奖励 领取时数字加
 */

type WeaponCollection struct {
	ID       int32 //配置ID
	Type     int32
	Progress int32
}

type StarMap struct {
	Level       int32
	Exp         int32
	MoonCount   int32
	Collections map[int32]*WeaponCollection
}

type RoleStarMap struct {
	starMap      *StarMap
	starMapDitry map[int32]bool
	dbDirty      bool
}

func FuncNewStarMap() *StarMap {
	//星图
	ret := &StarMap{
		Level:       int32(1),
		Exp:         int32(0),
		MoonCount:   int32(0),
		Collections: map[int32]*WeaponCollection{},
	}
	for _, smC := range table_WeaponCollection.Table_.IDMap {
		ret.Collections[smC.ID] = &WeaponCollection{
			ID:       smC.ID,
			Type:     smC.Type,
			Progress: int32(0),
		}
		if smC.Type == int32(6) {
			ret.Collections[smC.ID].Progress = smC.Target
		}
	}
	return ret
}

//检测星图是否初始化完成 并添加
func (this *RoleStarMap) CheckStarMap() {
	for _, smC := range table_WeaponCollection.Table_.IDMap {
		if this.starMap.Collections[smC.ID] == nil {
			this.starMap.Collections[smC.ID] = &WeaponCollection{
				ID:       smC.ID,
				Type:     smC.Type,
				Progress: 0,
			}
			if smC.Type == int32(6) {
				this.starMap.Collections[smC.ID].Progress = smC.Target
			}
		}
	}
}

func (this *StarMap) GetWeaponCollection(wcID int32) *WeaponCollection {
	return this.Collections[wcID]
}

func (this *RoleStarMap) GetStarMap() *StarMap {
	return this.starMap
}

func (this *RoleStarMap) AddStarMoon(count int32) {
	this.starMap.MoonCount += count
	this.SetDirtyFlag()
	//dirty
}

func (this *RoleStarMap) AddStarMapShard(typeID, count int32) {
	var tableID int32 = 0
	for _, v := range table_WeaponCollection.Table_.IDMap {
		if v.Type == typeID {
			tableID = v.ID
			break
		}
	}
	if tableID == 0 {
		return
	}

	weaponCollection := this.starMap.Collections[tableID]
	if weaponCollection == nil {
		this.starMap.Collections[tableID] = &WeaponCollection{
			ID:       tableID,
			Type:     typeID,
			Progress: count,
		}
	} else {
		weaponCollection.Progress += count
	}

	this.SetDirtyFlag()
	this.starMapDitry[tableID] = true
}

//星图升级
func (this *RoleStarMap) StarMapUpLevel() bool {
	SMDef := table_StarMap.Table_.LevelMap[this.starMap.Level]
	nextSMDef := table_StarMap.Table_.LevelMap[this.starMap.Level+1]
	if SMDef == nil || nextSMDef == nil {
		return false
	}

	if this.starMap.Exp < SMDef.CostExp {
		return false
	}

	if this.starMap.MoonCount < SMDef.CostMoon {
		return false
	}
	this.starMap.Level += 1
	this.starMap.Exp -= SMDef.CostExp
	this.starMap.MoonCount -= SMDef.CostMoon

	this.SetDirtyFlag()
	return true
}

//领取星图收集奖励
func (this RoleStarMap) GetWeaponCollectionAward(wcID, count int32) bool {
	c := this.starMap.Collections[wcID]
	if c == nil {
		return false
	}

	//读表
	WCDef := table_WeaponCollection.Table_.IDMap[wcID]
	if WCDef == nil {
		return false
	}
	if c.Type == int32(6) {
		for i := int32(0); i < count; i++ {
			this.starMap.Exp += WCDef.Award[c.Progress-1].StarMapExp
			c.Progress += 1
		}
	} else {
		for i := int32(0); i < count; i++ {
			c.Progress -= WCDef.Target
			this.starMap.Exp += WCDef.Award[0].StarMapExp
		}
	}

	this.starMapDitry[c.ID] = true
	this.SetDirtyFlag()

	return true
}

//打包星图
func (this *RoleStarMap) PackAllStarMap() *cs_message.StarMap {
	SMDef := table_StarMap.Table_.LevelMap[this.starMap.Level]
	if SMDef == nil {
		return nil
	}
	toC := &cs_message.StarMap{
		Level:     proto.Int32(this.starMap.Level),
		Exp:       proto.Int32(this.starMap.Exp),
		MoonCount: proto.Int32(this.starMap.MoonCount),
		ID:        proto.Int32(SMDef.ID),
	}

	for _, v := range this.starMap.Collections {
		wc := &cs_message.WeaponCollection{
			ID:       proto.Int32(v.ID),
			Progress: proto.Int32(v.Progress),
		}
		toC.WeaponCollections = append(toC.WeaponCollections, wc)
	}

	return toC
}

func (this *RoleStarMap) PackAllStarMapModify() *cs_message.StarMap {

	SMDef := table_StarMap.Table_.LevelMap[this.starMap.Level]
	if SMDef == nil {
		return nil
	}
	toC := &cs_message.StarMap{
		Level:     proto.Int32(this.starMap.Level),
		Exp:       proto.Int32(this.starMap.Exp),
		MoonCount: proto.Int32(this.starMap.MoonCount),
		ID:        proto.Int32(SMDef.ID),
	}

	for id, b := range this.starMapDitry {
		if b {
			delete(this.starMapDitry, id)
			weaponCollection := this.starMap.Collections[id]
			if weaponCollection != nil {
				wc := &cs_message.WeaponCollection{
					ID:       proto.Int32(weaponCollection.ID),
					Progress: proto.Int32(weaponCollection.Progress),
				}
				toC.WeaponCollections = append(toC.WeaponCollections, wc)
			}
		}
	}

	return toC

}

func (this *RoleStarMap) PackJson(fields map[string]interface{}) {
	if this.dbDirty {
		jsonStr, err := json.Marshal(this.starMap)
		if nil == err {
			this.dbDirty = true
			fields["starMap"] = jsonStr
		}
	}
}

func (this *RoleStarMap) IsDirty() bool {
	return this.dbDirty

}

func (this *RoleStarMap) SetDirtyFlag() {
	this.dbDirty = true
}

func (this *RoleStarMap) ClearDirtyFlag() {
	this.dbDirty = false
}

func (this *RoleStarMap) Init(starMap_ *StarMap) {
	this.starMap = starMap_
	this.starMapDitry = map[int32]bool{}
}
